package fast.loader;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import fast.data.StatBlock;


public class GemDB {
	
	private HashMap<Integer,Gem> gemDB = new HashMap<Integer,Gem>();
	GearBuffDB gearBuffDB = new GearBuffDB();
	
	ObjectDB<Gem> objectDB = new ObjectDB<Gem>("gems");
	
	public GemDB(FastLoader loader){
//		loadFromStorage();
//		objectDB.serialize(gemDB);
		if(objectDB.exists())
			gemDB = objectDB.deserialize();
		else{
			loadFromStorage();
			objectDB.serialize(gemDB);
		}
	}
	
	public Gem getGem(int id){
		if(!gemDB.containsKey(id)){
			Gem item = this.getGemFromWOWHEAD(id);
			if(item != null)
				gemDB.put(item.getId(), item);
		}
		//System.out.println("load from db: "+ id);
		return (Gem) gemDB.get(id);
	}
	
	public HashMap<Integer,Gem> getDB(){
		return gemDB;
	}
	
	public void loadFromStorage(){		
		File file = new File("./gems/");
		if(!file.exists()){
			file.mkdir();
		}
		else if(file.exists()){
			System.out.println("Path /gems/ exists");
			File[] files = file.listFiles();
			for(int i = 0;i< files.length;i++){
				if(files[i].isFile()){
					int gemid = Integer.parseInt(files[i].getName().split("\\.")[0]);
					Gem gem = this.getGemFromWOWHEAD(gemid);
					if(gem != null)
						gemDB.put(gem.getId(), gem);
				}
			}
		}
		System.out.println("directory gems imported");
	}
	
	private JSONObject getGemDataWowHead(int item_id){
		
		JSONObject stats = null;
		String json = "";
		
		File file = new File("./gems/"+item_id+".xml");
		if(!file.exists()){
			json = FastLoader.loadURL("http://"+FastLoader.wowheadPrefix+".wowhead.com/item=" + item_id + "&xml");
		
			try {
				//System.out.println("Write to db: " + id);
				//File file = new File("./wowhead/"+item_id+".xml");
				PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file)));
				out.write(json);
				out.flush();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		else{
			BufferedReader in;
			try {
				in = (new BufferedReader(new FileReader(file)));
				json = in.readLine();
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		//System.out.println(json);
		try {
	        DocumentBuilderFactory dbf =
	            DocumentBuilderFactory.newInstance();
	        DocumentBuilder db = dbf.newDocumentBuilder();
	        InputSource is = new InputSource();
	        is.setCharacterStream(new StringReader(json));

	        Document doc = db.parse(is);
	        NodeList nodes = doc.getElementsByTagName("jsonEquip");
	        NodeList nodes2 = doc.getElementsByTagName("json");
	        
	        NodeList nodes3 = doc.getElementsByTagName("name");
	        NodeList nodes4 = doc.getElementsByTagName("icon");
	        
	        NodeList nodes6 = doc.getElementsByTagName("quality");

	        Element element = (Element) nodes.item(0);
	        if(element != null){
		        stats = new JSONObject("{" + element.getTextContent()+ "}");
		        Element element2 = (Element) nodes2.item(0);
		        JSONObject stats2 = new JSONObject("{" + element2.getTextContent()+ "}");
		        stats.put("extra", stats2);
	           
		        Element element3 = (Element) nodes3.item(0);
		        String stats3 = element3.getTextContent();
		        stats.put("name", stats3);
		        
		        Element element4 = (Element) nodes4.item(0);
		        String stats4 = element4.getTextContent();
		        stats.put("icon", stats4);
		        
		        Element element6 = (Element) nodes6.item(0);
		        String stats6 = element6.getAttribute("id");
		        stats.put("quality", stats6);
	        }
	    }
	    catch (Exception e) {
	    	System.err.println(item_id);
	    	System.err.println(json);
	        e.printStackTrace();
	    }
	    return stats;
	}
	
	public Gem getGemFromWOWHEAD(int id){
		Gem gem = new Gem();
		
		JSONObject data = getGemDataWowHead(id);
		JSONObject extra;
		try {
			extra = data.getJSONObject("extra");

			//System.out.println(data.toString(1));
			
			gem.setName(data.getString("name"));
			gem.setIcon(data.getString("icon"));
			gem.setQuality(data.getInt("quality"));
			
			gem.add(new StatBlock(data));
			
			if(extra.has("id"))
				gem.setId(extra.getInt("id"));
			if(extra.has("subclass"))
				gem.setType(extra.getInt("subclass"));
			if(data.has("reqskill")){
				gem.setReqSkill(data.getInt("reqskill"));
			}
			if(gearBuffDB.isCritMetaGem(id))
				gem.setGearBuff("metagem_critdmg");
			if(gearBuffDB.isCapacitivePrimalDiamond(id))
				gem.setGearBuff("capacitive_primal_diamond");

		} catch (JSONException e) {
			e.printStackTrace();
		} catch (NullPointerException e) {
			//e.printStackTrace();
			return null;
		}
		
		return gem;
	}
}
